package com.demo.service;

import com.demo.annotation.ShardingStrategy;
import com.demo.dao.mapper.AddressMapper;
import com.demo.dao.mapper.UserMapper;
import com.demo.model.Address;
import com.demo.model.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.PayloadApplicationEvent;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 测试 ShardingJDBC 分库
 * @author K
 */
@Slf4j
@Service
public class DbShardingStrategyService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private AddressMapper addressMapper;

    @Resource
    private ApplicationEventPublisher applicationEventPublisher;

    @ShardingStrategy(shardingColumn = "#userId")
    public void insertByShardingValue(Long userId) {
        User user = new User();
        user.setUserId(userId);
        userMapper.insertSelective(user);

        final Address address = new Address();
        address.setUserId(userId);
        address.setUserAddress(userId.toString());
        addressMapper.insertSelective(address);
    }

    /**
     * 通过用户id获取数据，并且根据用户id进行分库查询
     * @param userId 用户id
     * @return List<User>
     */
    @ShardingStrategy(shardingColumn = "#userId")
    public List<User> selectByUserId(Long userId) {
        return userMapper.queryByUserId(userId);
    }

    @ShardingStrategy(shardingColumn = "#userId")
    public List<Address> selectByAddrUserId(Long userId) {
        return addressMapper.queryByUserId(userId);
    }

    @Transactional(rollbackFor = Exception.class)
    @ShardingStrategy(shardingColumn = "#userId")
    public void insertAfterPublisher(Long userId) {
        User user = new User();
        user.setUserId(userId);
        userMapper.insertSelective(user);
        log.info("user 保存成功");
        applicationEventPublisher.publishEvent(new PayloadApplicationEvent<>("insert", user));
    }

    @Transactional(rollbackFor = Exception.class)
    @ShardingStrategy(shardingColumn = "#userId")
    public void insertAfterPublisherForAddr(Long userId) {
        Address address = new Address();
        address.setUserId(userId);
        address.setUserAddress(userId.toString());
        addressMapper.insertSelective(address);
        log.info("address 保存成功");
        applicationEventPublisher.publishEvent(new PayloadApplicationEvent<>("insert", address));
    }
}
